//
//  LAArrowPolylineRender.m
//  2bulu-NewAssistant
//
//  Created by Kent Peifeng Ke on 2/6/15.
//  Copyright (c) 2015 È≠èÊñ∞Êù∞. All rights reserved.
//

#import "LAArrowPolylineRender.h"

#import <pthread.h>
#import <FoundationUtilities/graphicsMath.h>



NS_INLINE double nearDistanceBetweenPoints(CGPoint p1, CGPoint p2)
{
    double delX = fabs(p2.x - p1.x);
    double delY = fabs(p2.y - p1.y);
    double ref = delX;
    float k;
    if(delY > delX)
    {
        k = delX/delY;
        ref = delY;
    }
    else
        k = delY/delX;
    
    if(k>0.9)
        return 1.4*ref;
    if(k>0.75)
        return 1.3*ref;
    if(k>0.57)
        return 1.2*ref;
    if(k>0.32)
        return 1.1*ref;
    
    return ref;
}



#define INTER_HALF_ARROW_ANGLE 0.3

#define INTER_INVALID_ARROW_COUNT (-1)


#pragma pack(1)
typedef struct
{
    MKMapPoint *subSegPoints;
    int subSegPointCount;
    MKMapRect subSegBoundingRect;
    GradientsColorCompnent *subSegColors;
    int subSegColorCount;
}SubSegPointsType;
#pragma pack()


@implementation LAArrowPolylineRender
{
    MKPolyline * polyline;
    
    SubSegPointsType *_subPolyLines;
    unsigned int _subPolyLineCount;
    volatile float _zoomScale;
    
}

@synthesize pointsColors = _pointsColors;
@synthesize colorCount = _colorCount;


-(id) initWithOverlay:(id<MKOverlay>)overlay
{
    self = [super initWithOverlay:overlay];
    if (self)
    {
        polyline = ((MKPolyline*)self.overlay);
        _colorCount = 0;
        
        [self publicInitial];
        
    }
    return self;
}


-(instancetype)initWithPolyline:(MKPolyline *)pline andPointsColors:(GradientsColorCompnent *)colors colorCount:(NSUInteger)count
{
    self = [super initWithPolyline:pline];
    if (self)
    {
        
        polyline = ((MKPolyline*)self.overlay);
        if(colors)
            [self setPointsColors:colors count:count];
        
        [self publicInitial];
        
    }
    return self;
}

-(void)publicInitial
{
  //  [self createSubSegPoints];
}

-(void)setPointsColors:(GradientsColorCompnent *)colors count:(NSUInteger)count
{
    if(_colorCount < count)
    {
        if(_pointsColors)
            free(_pointsColors);
        _pointsColors = NULL;
    }
    
    _colorCount = count;
    
    if(!_pointsColors)
        _pointsColors = calloc(count, sizeof(GradientsColorCompnent));
    
    
    memcpy(_pointsColors, colors, count*sizeof(GradientsColorCompnent));
    
}


-(void)createSubSegPoints
{
    if(_subPolyLines)
        return;
    
    size_t sz = sizeof(SubSegPointsType);
    int segMaxPointCount = 15000;
    
    NSInteger totalPointCount = self.polyline.pointCount;
    NSInteger leftPointCnt = totalPointCount;
    NSInteger leftColorCnt = _colorCount;
    double r = (double)(totalPointCount-1)/(segMaxPointCount-1);
    int segCount = ceil(r);
    if(segCount > 0)
    {
        _subPolyLines = calloc(segCount, sz);
        SubSegPointsType *p = _subPolyLines;
        
        for(int i=0,x=1; ;x++)
        {
            SubSegPointsType subSeg;
            
            if(i>0) //多取一个前一段的点
            {
                i -= 1;
                leftPointCnt += 1;
            }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
            subSeg.subSegPointCount = MIN(segMaxPointCount, leftPointCnt);
#pragma clang diagnostic pop
            subSeg.subSegPoints = self.polyline.points+i;
            if(_pointsColors && leftColorCnt>0)
            {
                subSeg.subSegColors = _pointsColors+i;
                subSeg.subSegColorCount = (int)MIN(leftColorCnt, subSeg.subSegPointCount);
                leftColorCnt -= subSeg.subSegColorCount;
            }
            else
            {
                subSeg.subSegColors = NULL;
                subSeg.subSegColorCount = 0;
            }
            
            MKMapPoint mp1 = subSeg.subSegPoints[0];
            MKMapPoint mp2;
            
            double maxX = mp1.x;
            double minX = mp1.x;
            double maxY = mp1.y;
            double minY = mp1.y;
            
            for(int j=1;j<subSeg.subSegPointCount;j++)
            {
                mp2 = subSeg.subSegPoints[j];
                
                if(mp2.x > maxX)
                    maxX = mp2.x;
                else if(mp2.x <minX)
                    minX = mp2.x;
                
                if(mp2.y > maxY)
                    maxY = mp2.y;
                else if(mp2.y < minY)
                    minY = mp2.y;
                
            }
            subSeg.subSegBoundingRect = MKMapRectMake(minX, minY, maxX-minX, maxY-minY);
            
            *p = subSeg;
            p++;
            i += subSeg.subSegPointCount;
            
            leftPointCnt -= subSeg.subSegPointCount;
            
            if(leftPointCnt <= 0)
                break;
            
        }
        
    }
    _subPolyLineCount = segCount;
    
}




-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
//    MKMapRect overlayBoundingRect = self.overlay.boundingMapRect;
    //有些绘制要超出边界区域，所以这里不要直接返回
//    if(!MKMapRectIntersectsRect(overlayBoundingRect,mapRect))
//        return;

    if(!_subPolyLines)
    {
        @synchronized(self)
        {
            [self createSubSegPoints];
        }
    }

    
    CGRect mapRectCG = [self rectForMapRect:mapRect];
    
    double k = CGContextConvertSizeToUserSpace(context, (CGSize){1,1}).width*self.contentScaleFactor;
    CGFloat lineWidth = k*self.lineWidth;
    MKMapRect actualOccupiedRect = MKMapRectInset(mapRect, -lineWidth, -lineWidth+k);//判断区域要扩大一些，这样可以保证处于区域边缘的线条可以正确绘制，避免残缺
    //绘制轨迹线
    for(int sidx=0; sidx<_subPolyLineCount; sidx++)
    {
        SubSegPointsType *curSeg = _subPolyLines+sidx;
        
        if(!MKMapRectIntersectsRect(curSeg->subSegBoundingRect,actualOccupiedRect))
            continue;
        
        [self drawLineforSubSeg:*curSeg inMapRect:actualOccupiedRect zoomScale:zoomScale inContext:context];
        
    }

    //所有参赛都不能为nil
#if TARGET_OS_IPHONE
    void (^drawText)(UIColor *, NSDictionary *, MKMapPoint, NSString *) = ^(UIColor *backgroundColor, NSDictionary *textAttribute, MKMapPoint postion, NSString *text)
#else
    void (^drawText)(NSColor *, NSDictionary *, MKMapPoint, NSString *) = ^(NSColor *backgroundColor, NSDictionary *textAttribute, MKMapPoint postion, NSString *text)
#endif
    {
        CGSize s = [text sizeWithAttributes:textAttribute];
        CGPoint p =  [self pointForMapPoint:postion];
        CGRect f1 = CGRectMake(p.x-s.width/2, p.y-s.height/2, s.width, s.height);
        CGFloat extend = s.height*0.2;
        CGRect f = CGRectInset(f1, -extend, -extend);
        if(f.size.width<f.size.height)
        {
            f.origin.x -= (f.size.height - f.size.width)/2;
            f.size.width = f.size.height;
        }
        
        if(CGRectIntersectsRect(f, mapRectCG))
        {
            CGContextSaveGState(context);
            CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
#if TARGET_OS_IPHONE
            CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
#else
            CGContextSetStrokeColorWithColor(context, [NSColor whiteColor].CGColor);
#endif
            CGContextSetLineWidth(context, extend/2);
            CGFloat w = MIN(f.size.width, f.size.height);
            CGPathRef path = CGPathCreateWithRoundedRect(f, w/2, w/2, NULL);
            CGContextAddPath(context, path);
            CGContextFillPath(context);
            //要对同一条path进行stroke的话，需要再add一次
            CGContextAddPath(context, path);
            CGContextStrokePath(context);
            CGContextRestoreGState(context);
            CGPathRelease(path);
#if TARGET_OS_IPHONE
            //NSString(NSStringDrawing)的方法属于UIKit，所以要有UIGraphicsPushContext(context);
            UIGraphicsPushContext(context);
            [text drawInRect:f1 withAttributes:textAttribute];
            UIGraphicsPopContext();
#else
            [text drawInRect:f1 withAttributes:textAttribute];
#endif
//            CGContextSaveGState(context);
//            [text drawInRect:f1 withAttributes:textAttribute];
//            CGContextRestoreGState(context);

        }
    };
#if TARGET_OS_IPHONE
    UIFont *f = self.markStringFont;
    if(!f)
        f = [UIFont systemFontOfSize:12];
    
    f = [f fontWithSize:f.pointSize*k];
    NSDictionary *attri = @{NSFontAttributeName:f,NSForegroundColorAttributeName:[UIColor whiteColor]};
#else
    NSFont *f = self.markStringFont;
    if(!f)
        f = [NSFont systemFontOfSize:12];
    f = [NSFont fontWithName:f.fontName size:f.pointSize*k];
    NSDictionary *attri = @{NSFontAttributeName:f,NSForegroundColorAttributeName:[NSColor whiteColor]};
#endif
    
    MKMapPoint startPoint = self.polyline.points[0];
    MKMapPoint endPoint = self.polyline.points[self.polyline.pointCount-1];
    if(self.reverseArrow)
    {
        MKMapPoint tp = startPoint;
        startPoint = endPoint;
        endPoint = tp;
    }
    
#if TARGET_OS_IPHONE
    if(self.startPointMarkString)
        drawText([UIColor colorWithRed:65.0/255 green:141.0/255 blue:52.0/255 alpha:1.0],attri,startPoint,self.startPointMarkString);
    if(self.endPointMarkString)
        drawText([UIColor redColor],attri,endPoint,self.endPointMarkString);

#else
    if(self.startPointMarkString)
        drawText([NSColor colorWithRed:65.0/255 green:141.0/255 blue:52.0/255 alpha:1.0],attri,startPoint,self.startPointMarkString);
    if(self.endPointMarkString)
        drawText([NSColor redColor],attri,endPoint,self.endPointMarkString);
#endif
    

#if DEBUG
    //调试用代码
    CGContextSaveGState(context);
    // CGFloat roadWidth = MKRoadWidthAtZoomScale(zoomScale);
#if TARGET_OS_IPHONE
    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
#else
    CGContextSetStrokeColorWithColor(context, [NSColor whiteColor].CGColor);
#endif
    CGContextSetAlpha(context, 0.7);
    CGContextSetLineWidth(context, k);
    CGContextStrokeRect(context,mapRectCG);
    //  CGContextSetAlpha(context, 0.2);
    // CGContextSetFillColorWithColor(context, [UIColor magentaColor].CGColor);
    // CGContextFillRect(context, CGRectInset(mapRectCG, mapRectCG.size.width/20, mapRectCG.size.height/20));
    //    调试用代码 end
    CGContextRestoreGState(context);
#endif
    
}




- (BOOL)canDrawMapRect:(MKMapRect)mapRect
             zoomScale:(MKZoomScale)zoomScale
{
    BOOL can = [super canDrawMapRect:mapRect zoomScale:zoomScale];
    _zoomScale = zoomScale;
    return can;
}


//绘制渐变色 罗亮富 added  2016.12.24
-(void)drawLineforSubSeg:(SubSegPointsType)subSegPointsInfo inMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    double k = CGContextConvertSizeToUserSpace(context, (CGSize){1,1}).width*self.contentScaleFactor;
    CGFloat lineWidth = k*self.lineWidth*0.7;
    CGRect mapRectCG = [self rectForMapRect:mapRect];
    SubSegPointsType subLine = subSegPointsInfo;
    
    MKMapPoint *mapPoints = subLine.subSegPoints;
    int pointCount = subLine.subSegPointCount;
    NSInteger totalPointCount = self.polyline.pointCount;
    GradientsColorCompnent *colorVals =  subLine.subSegColors;
    int colorCount = 0;
    if(colorVals)
        colorCount = subSegPointsInfo.subSegColorCount;
    
    
    /* 每一个zoomScale对应的 地图等级
     zoomScale     level      skip+
     0.0625000      15          0
     0.0312500      14
     0.0156250      13
     0.0078125      12
     0.0039062      11
     0.0019531      10
     0.0009766      9
     0.0004883      8
     */
    
    int skip = 1;
    if(zoomScale < 0.0625000 && totalPointCount > 5000)
    {
        skip = 0.0312500/zoomScale;
        if(totalPointCount/skip < 1000)
            skip = (int)(totalPointCount/1000);
        if(skip < 1)
            skip = 1;
    }
    
    
    CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
    //如果_pointsColors的数值长度不够，剩余部分的轨迹线用self.strokeColor的颜色
    CGFloat strokeColorComponents[4];
    [self.strokeColor getRed:strokeColorComponents green:strokeColorComponents+1 blue:strokeColorComponents+2 alpha:strokeColorComponents+3];
    CGColorRef strokeColor =  CGColorCreate(cSpace, strokeColorComponents);
    
    CGFloat rigidLineGradientLocation[2] = {0,1};
    // CGFloat bezierLineGradientLocation[3];//需要在使用的时候设置各渐变位置的值
    CGFloat components[12];//绘制直线的时候只需要8个元素，只有绘制bezier的时候才需要12个都用上
    
    int disSkipCont = 0; //因为距离太近而连续跳过的点数
#if DEBUG
    int totalDisSkipCount = 0;
    // int totalBezierCount = 0;
    int totalRigidCount = 0;
#endif
    
    CGFloat deltaX, deltaY;
    unsigned long preIndex = 0;
    GradientsColorCompnent c1, c2;
    //   BOOL curDrawBezierLine = NO;
    BOOL lastCross = YES;
    BOOL smoothc = self.smoothColorJoin;
    
    
    CGLineJoin tlineJoin = self.lineJoin; // defaults to kCGLineJoinRound
    CGLineCap tlineCap = self.lineCap; // defaults to kCGLineCapRound
    CGFloat tmiterLimit = self.miterLimit; // defaults to 10
    
    CGPoint p1 = [self pointForMapPoint:*(mapPoints)];
    CGPoint p2;
    CGFloat lastArrowDis = 0;//上一次绘制的最后一个箭头到线段最后一个点的距离
    CGFloat arrowDis = k*50;//箭头间距
    CGFloat arrowEdgeLen = k*4;
    
    CGMutablePathRef arrowPath = CGPathCreateMutable();
    
    CGContextSaveGState(context);
    CGContextSetLineWidth(context, lineWidth);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    CGContextSetStrokeColorWithColor(context, strokeColor);
    
    int i = skip;
    for(;i<pointCount; i+=skip)
    {
        preIndex = i-skip-skip*disSkipCont;
        //    printf("\nfor start---> i:%d skip:%d disSkipCont:%d preIndex:%lu\n",i,skip,disSkipCont,preIndex);
        //drawPolyLineCode标签放在此处，因为在goto drawPolyLineCode:之前有可能会重新设置preIndex的值
    drawPolyLineCode:
        if(!LineCorssOverMapRect(mapRect,*(mapPoints+preIndex),*(mapPoints+i)))
        {
            lastCross = NO;
            //  printf("lastCross == NO countinue\n");
            continue;
        }
        
        //  @autoreleasepool //手动做了释放处理，不需要autorelease
        {
            if(!lastCross)
                p1 = [self pointForMapPoint:*(mapPoints+preIndex)];
            
            p2 = [self pointForMapPoint:*(mapPoints+i)];
            
            lastCross = YES;
            
            deltaX = fabs(p2.x-p1.x)/k;
            deltaY = fabs(p2.y-p1.y)/k;
            
            if(deltaX<1.1 && deltaY<1.1)//两点间距离太近,且不是最后一个点
            {
                disSkipCont++;
                //   printf("disSkipCont++ =:%d countinue \n",disSkipCont);
                continue;
            }
            
            CGMutablePathRef dPath = CGPathCreateMutable();
            CGPathMoveToPoint(dPath, NULL, p1.x, p1.y);
            CGPathAddLineToPoint(dPath, NULL, p2.x, p2.y);
            
#if DEBUG
            totalDisSkipCount += disSkipCont;
#endif
            disSkipCont = 0;
            //  printf("RESET disSkipCont == 0\n");
            
            if(i<colorCount) //颜色数组元素未超出，使用颜色数组中的色值
            {
                c1 = colorVals[i-skip];
                components[0] = c1.r;
                components[1] = c1.g;
                components[2] = c1.b;
                components[3] = c1.a;
                if(smoothc)
                {
                    c2 = colorVals[i];
                    components[4] = c2.r;
                    components[5] = c2.g;
                    components[6] = c2.b;
                    components[7] = c2.a;
                    
                    CGContextSaveGState(context);
                    CGContextSetLineWidth(context, lineWidth);
                    
                    CGFloat *gradientColors = components;
                    CGGradientRef gradient = CGGradientCreateWithColorComponents(cSpace, gradientColors, rigidLineGradientLocation, 2);
                    
                    CGPathRef pathToFill = CGPathCreateCopyByStrokingPath(dPath, NULL, lineWidth, tlineCap, tlineJoin, tmiterLimit);
                    CGContextAddPath(context, pathToFill);
                    CGContextClip(context);
                    CGContextDrawLinearGradient(context, gradient, p1, p2, kCGGradientDrawsAfterEndLocation);
                    //   CGContextDrawPath(context, kCGPathFillStroke);//no need
                    CGGradientRelease(gradient);
                    CGPathRelease(pathToFill);
                    CGContextRestoreGState(context);
                }
                else
                {
                    CGContextSaveGState(context);
                    CGColorRef c =  CGColorCreate(cSpace, components);
                    CGContextSetStrokeColorWithColor(context, c);
                    CGColorRelease(c);
                    
                    CGContextAddPath(context, dPath);
                    CGContextStrokePath(context);
                    CGContextRestoreGState(context);
                }
            }
            else //范围超出颜色数组，使用默认
            {
                CGContextSaveGState(context);
                // CGContextSetStrokeColorWithColor(context, strokeColor);
                CGContextAddPath(context, dPath);
                CGContextStrokePath(context);
                CGContextRestoreGState(context);
            }
            
            lastArrowDis = [self arrowsBetweenPoints:p1
                                                 and:p2
                                   lastArrowDistance:lastArrowDis
                                        withArrowGap:arrowDis
                                          edgeLength:arrowEdgeLen
                                      constraintRect:mapRectCG
                                       shouldReverse:self.reverseArrow
                                           withBlock:^(CGPoint p_1, CGPoint p_2, CGPoint p_vertex) {
                                               
                                               CGPathMoveToPoint(arrowPath, NULL, p_1.x, p_1.y);
                                               CGPathAddLineToPoint(arrowPath, NULL, p_vertex.x, p_vertex.y);
                                               CGPathAddLineToPoint(arrowPath, NULL, p_2.x, p_2.y);
                                               
                                               
                                           }];
            
            CGPathRelease(dPath);
            
            p1 = p2;
        }
    }
    
    //如果skip了最后一个点，要倒回去再检查一遍，目的是为了保证最后的点不会被因为抽稀而跳过\
    另外(i-skip)<(pointCount-1)必须是小于，不然在满足goto条件的时候会陷入死循环，因为goto后再回来 (i-skip)==(pointCount-1)
    if(skip>1 && i>=pointCount &&  (i-skip)<(pointCount-1) && (i-skip) >= 0 )
    {
        i = pointCount - 1;
        
        goto drawPolyLineCode;
    }
    
#if DEBUG
    //    if( totalRigidCount > 0)
    //        NSLog(@"===>> totalDisSkipCount:%d totalRigidCount:%d skip = %d",totalDisSkipCount,totalRigidCount,skip);
#endif
    
    //绘制箭头的path
    CGContextSetLineWidth(context, k);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineJoin(context, kCGLineJoinMiter);
#if TARGET_OS_IPHONE
    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
#else
    CGContextSetStrokeColorWithColor(context, [NSColor whiteColor].CGColor);
#endif
    CGContextAddPath(context, arrowPath);
    CGContextStrokePath(context);
    
    CGContextRestoreGState(context);
    CGPathRelease(arrowPath);
    CGColorRelease(strokeColor);
    CGColorSpaceRelease(cSpace);
}



//往arPath添加箭头，返回最后一个箭头与p2的距离，dis1：之前最后一个箭头与p1的距离
-(CGFloat)arrowsBetweenPoints:(CGPoint)p1
                      and:(CGPoint)p2
          lastArrowDistance:(CGFloat)preDisLeft
             withArrowGap:(CGFloat)gap
                 edgeLength:(CGFloat)r
             constraintRect:(CGRect)rect
            shouldReverse:(BOOL)shouldReverse
                   withBlock:(nonnull void (^)(CGPoint p_1,CGPoint p_2,CGPoint p_vertex))pointBlock
{
    double aDis = preDisLeft;
    if(aDis > gap)
        aDis = 0;//控制得好的话 应该不会跑这一行
    
    double p1top2 = nearDistanceBetweenPoints(p1, p2);
    double leftDis = aDis + p1top2;
    if(leftDis < gap)
        return leftDis;
    
    double deltaX = p2.x - p1.x;
    double deltaY = p2.y - p1.y;
    
    //计算角度
    double angle;
    if(fabs(deltaX)<0.01)
        angle = M_PI_2;
    else
        angle = atan(deltaY/deltaX);
    
    if(p2.x > p1.x)
        angle = angle+M_PI;
    
    if (shouldReverse)
        angle += M_PI; //调转方向
    
    
    double ratio = gap/p1top2;
    double xIncrease = deltaX*ratio;
    double yIncrease = deltaY*ratio;
    double initialRatio = (gap-aDis)/gap;
    
    double angles1 = angle - INTER_HALF_ARROW_ANGLE;
    double angles2 = angle + INTER_HALF_ARROW_ANGLE;
    CGPoint vertex = CGPointMake(p1.x+xIncrease*initialRatio, p1.y+yIncrease*initialRatio);
    CGPoint p0 = CGPointMake(vertex.x+r*cos(angles1), vertex.y+r*sin(angles1));
    CGPoint p3 = CGPointMake(vertex.x+r*cos(angles2), vertex.y+r*sin(angles2));
    
    int maxArrowCount = p1top2/aDis;
    
#warning 方案实现未完成，实际验证效果看不优化也是可以接受的
    if(0)//maxArrowCount > 10)//aDis不是很小的话，说明是长直线
    {
//       BOOL firstVertexInRegion = CGRectContainsPoint(rect, vertex);
//
//
//        CGPoint bVertex = vertex;
//        //利用二分查找，找到在rect区域里的任一点
//
//        int minIndx = 0;
//        int maxIndex = maxArrowCount - 1;
//        int midIndx = (maxIndex - minIndx)/2;
//        while (maxIndex>minIndx)
//        {
//            CGPoint bVertex = CGPointMake(bVertex.x+xIncrease*midIndex, bVertex.y+yIncrease*midIndex);
//            if(!CGRectContainsPoint(rect, bVertex))
//            {
//
//            }
//        }

    }
    else
    {
        if(CGRectContainsPoint(rect, vertex))
            pointBlock(p0,p3,vertex);
        leftDis -= gap;
        while(leftDis > gap)//总距离大于箭头间距才绘制
        {
            //由于第一步就已经计算好了箭头的各个点，剩下的就只需要做平移运算了，是不是很聪明？
            vertex.x += xIncrease;
            vertex.y += yIncrease;
            p0.x += xIncrease;
            p0.y += yIncrease;
            p3.x += xIncrease;
            p3.y += yIncrease;
            if(CGRectContainsPoint(rect, vertex))
                pointBlock(p0,p3,vertex);
            leftDis -= gap;
        }
    }
    
    return leftDis;
    
}


//-(void)addArrowAtPoint:(CGPoint)pstart
//             withAngle:(float)angle
//                length:(CGFloat)arrowLen
//               edgeLen:(CGFloat)eLen
//                toPath:(CGMutablePathRef)arrowPath
//{
//    double angles1 = angle - INTER_HALF_ARROW_ANGLE;
//    double angles2 = angle + INTER_HALF_ARROW_ANGLE;
//    double r = eLen;
//
//    BOOL arrowCeterLine = (arrowLen>1);
//    CGPoint endPoint = pstart;
//    if(arrowCeterLine)
//        endPoint = CGPointMake(pstart.x-arrowLen*cos(angle), pstart.y-arrowLen*sin(angle));
//    CGPoint p0 = CGPointMake(endPoint.x+r*cos(angles1), endPoint.y+r*sin(angles1));
//    CGPoint p3 = CGPointMake(endPoint.x+r*cos(angles2), endPoint.y+r*sin(angles2));
//
//    if(arrowCeterLine)
//    {
//        CGPathMoveToPoint(arrowPath,NULL, pstart.x, pstart.y);
//        CGPathAddLineToPoint(arrowPath, NULL, endPoint.x, endPoint.y);
//    }
//    CGPathMoveToPoint(arrowPath, NULL, p0.x, p0.y);
//    CGPathAddLineToPoint(arrowPath, NULL, endPoint.x, endPoint.y);
//    CGPathAddLineToPoint(arrowPath, NULL, p3.x, p3.y);
//
//}


-(void)freeSubLines
{
    if(_subPolyLines)
    {
        free(_subPolyLines);
    }
    
}

-(void)dealloc
{
    
    if(_pointsColors)
        free(_pointsColors);
    
    [self freeSubLines];
    
}


@end





